﻿#ifndef OPTIONITEMFRAME_H
#define OPTIONITEMFRAME_H

#include <QObject>
#include <QWidget>
#include "ui/optionWidget/optionsItem/pollDownBtn.h"
#include "ui/QSS/GlobalQss.h"
#include "ENUM/enum.h"
#include "ui/optionWidget/optionsItem/optionItemMiddleWidget/MiddleWidgetVirtual.h"
#include <QFrame>

/*
 * optionWidget中optionItem选项的框架
 * 在Qt中同一个类不可以既为模板类又提供信号槽机制"Q_OBJECT",但是这里框架即需要信号槽也需要模板，此时就得将两个分开，
 * 这里采用optionItem类实现信号槽机制，optionItemFrame类实现模板（optionItemFrame继承自optionItem）这样optionItemFrame类即有模板也能够实现信号槽机制
 * 这里通过多态的方法保证了上层optionWidget类可以通过optionItem的指针或者引用间接的调用optionItemFrame中的方法（前提是optionItemFrame必须对虚函数进行重写，并且返回值不能携带模板(携带模板参数无法推导模板类型)）
 */

class optionItem : public QWidget{
        Q_OBJECT
public:
    explicit optionItem(const QString& text, const QString &hidePath, const QString &showPath, QWidget *parent = nullptr);
    virtual void setMiddleWidgetVisible(bool isvisible) = 0;                                    // 用于设置中心控件的显示与隐藏，这里用纯虚函数表示，子类必须进行重写
    virtual int middleWidth(ParameterKind kind = ParameterKind::Get, int width = 0) = 0;        // 方便上层optionWidget类修改中心部件的宽度
    virtual bool setPaletteBF(const QColor& backgroundColor, const QColor& fontColor) = 0;      // 通过调色板修改当前组件的背景色与字体色必须重写
    virtual MiddleWidgetVirtual* RMiddleWidget() = 0;                                           // 返回中心部件的父类，因为中心部件都采用多态的方法，所以这里返回中心部件的父类指针就可以通过该指针访问到中心部件的方法了。
    virtual void middleWidgetLanguageInit() = 0;
    virtual void setPollDownText(const QString& text) = 0;
protected:
    pollDownBtn* btn;               // 下拉框按钮
    QFrame*      SplitLine;         // 分割线
    int generalFixedHeight = 70;
    int FixedWidth = 330;
private slots:
    void middleWidgetVisible(bool isVisible);
};

template  <class T>
class optionItemFrame : public optionItem
{

public:
     optionItemFrame(const QString &text, const QString &hidePath, const QString &showPath, T *middle, QWidget *parent = nullptr)
        :optionItem(text, hidePath, showPath, parent)
    {
        middleWidget = middle;
        VLayout = new QVBoxLayout(this);
        VLayout->addWidget(btn);
        VLayout->addWidget(middleWidget);
        VLayout->addWidget(SplitLine);
        VLayout->setMargin(0);
        this->setMiddleWidgetVisible(false);
        this->setFixedSize(FixedWidth, 80);
        middleWidget->fixedWidth(ParameterKind::Set, 300);
    }

    void setMiddleWidgetVisible(bool isvisible) override
    {
        if(isvisible)
        {
            this->setFixedSize(FixedWidth, generalFixedHeight + middleWidget->RFixedHeight() + 25);
        }
        else{
            this->setFixedSize(FixedWidth, 80);
        }
        middleWidget->setVisible(isvisible);
    }

    // 提供返回中心部件对象的接口方便后期完善功能需要获取中心部件使用， 后期上层使用auto获取即可。
   MiddleWidgetVirtual* RMiddleWidget() override
    {
        return middleWidget;
    }
     T* RCurrentMiddWidget()
     {
         return middleWidget;
     }

    // 修改下层中心部件的宽度(是对父类optionItem中的方法重写)
    int middleWidth(ParameterKind kind = ParameterKind::Get, int width = 0) override
    {
        if(!width)
        ELOG("中心框架尝试修改错误值0");
        if(kind == ParameterKind::Set && width != 0)
        {
            FixedWidth = width;
            middleWidget->fixedWidth(ParameterKind::Set, FixedWidth);
        }
        return FixedWidth;
    }

    bool setPaletteBF(const QColor& backgroundColor, const QColor& fontColor) override
    {
        QPalette palette;
        palette.setBrush(QPalette::Background, backgroundColor);
        palette.setColor(QPalette::WindowText, fontColor);
        this->setPalette(palette);
        this->setAutoFillBackground(true);
        middleWidget->setPaletteBF(palette);
        btn->setPaletteBF(palette);
        return true;
    }

    // 调用中间部件的语言初始化
    void middleWidgetLanguageInit() override
    {
        //DLOG("调用对应初始化语言");
        middleWidget->LanguageInit();
    }

    // 给当前下拉框label设置文字
    void setPollDownText(const QString& text) override
    {
        btn->setLabelText(text);
    }
private:
    T *middleWidget;        // optionItem中的中心部件
    QVBoxLayout *VLayout;   // 当前optionItemFrame的垂直布局
};

#endif // OPTIONITEMFRAME_H

